package com.biblum.topgas;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import com.biblum.topgas.R;
import com.google.ads.AdView;
import com.google.android.maps.GeoPoint;


public class TopGasActivity extends Activity implements LocationListener, TopGasDataListener {

	public static final String TAG = "TopGasActivity";
	
	public static final int MESSAGE_LOADING_START = 0;
	public static final int MESSAGE_LOADING_OK = 1;
	public static final int MESSAGE_LOADING_ERROR = 2;

	

	LocationManager manager;
	String providerFine, providerCoarse, lastLocationProvider;
	ProgressDialog loadingDialog;
	EstacionesData estacionesData;
	boolean fullscreen;
	boolean updateWhenLocationAvaiable = false;
    GeoPoint geoPoint;
    
	static long whenLoadedAutomatically = 0;

	public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        geoPoint = null;
        
		// No Titlebar
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		requestWindowFeature(Window.FEATURE_PROGRESS);

		setContentView(R.layout.menu_principal);
	    
		// Look up the AdView as a resource and load a request.
		MyAdManager.initialize(this);
	    MyAdManager.loadAd((AdView)this.findViewById(R.id.adView));
    
        estacionesData = EstacionesData.getInstance(this);
    }
	
	
	@Override
	protected void onResume() {
		super.onResume();

		estacionesData.addListener(this);
		estacionesData.setLang(getResources().getString(R.string.geonames_lang));

		//geoPoint = null;
		
		Log.d(TAG, "Loading preferences");
		SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);		
		fullscreen = sharedPrefs.getBoolean("fullscreen", false);

		// No Statusbar
		if (fullscreen) {
			getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		} else {
			getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		}
		
		manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		Criteria criteria = new Criteria();
		criteria.setAltitudeRequired(false);
		criteria.setBearingRequired(false);
		criteria.setCostAllowed(false);
		criteria.setPowerRequirement(Criteria.POWER_LOW);
        
		//criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setAccuracy(Criteria.ACCURACY_MEDIUM);		
		providerFine = manager.getBestProvider(criteria, true);
		Log.d(TAG, "USING location provider fine = " + providerFine);

		criteria.setAccuracy(Criteria.ACCURACY_COARSE);
		providerCoarse = manager.getBestProvider(criteria, true);
		Log.d(TAG, "USING location provider coarse = " + providerCoarse);
			
		if (providerFine == null && providerCoarse == null) 
		{
			Toast toast = Toast.makeText(getApplicationContext(), R.string.error_location, Toast.LENGTH_LONG);
			toast.setGravity(Gravity.CENTER, 0, 0);
			toast.show();
		}
		else 
		{
			lastLocationProvider = null;
			if (providerFine != null && providerCoarse != null && providerFine.equals(providerCoarse)) 
				providerCoarse = null;
			
			if (providerCoarse != null) 
				manager.requestLocationUpdates(providerCoarse, 5*60000, 100, this); // update each 5 minutes
			if (providerFine != null) 
				manager.requestLocationUpdates(providerFine, 5*60000, 100, this); // update each 5 minutes
		}
		
		Location location = null;
		if ( providerCoarse != null )
			location =  manager.getLastKnownLocation(providerCoarse);
		else if ( providerFine != null )
			location =  manager.getLastKnownLocation(providerFine);
		if ( location != null )
		{
			// ponemos un punto al principio, para cargar algo desde el servidor
			geoPoint = location2GeoPoint(location);		
			estacionesData.setLocationPoint(geoPoint);			
		}
		
		// actualizamos los descuentos con las preferencias
    	DescuentosData.getInstance().actualizarDescuentos(this);
    	
		// Actualiza al iniciar y cada media hora si no se cierra la aplicación
		//if ((System.currentTimeMillis() - whenLoadedAutomatically > 30*60))
		if ((System.currentTimeMillis() - whenLoadedAutomatically > 30*60*1000)) 			
		{
			updateData();
			whenLoadedAutomatically = System.currentTimeMillis();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
        estacionesData.removeListener(this);
		
		if (loadingDialog != null) {
			if (loadingDialog.isShowing()) loadingDialog.dismiss();
			loadingDialog = null;
		}
		
		// To save battery
		if (manager != null) manager.removeUpdates(this);
	}

	private void updateData() {
		Log.d(TAG, "updateData()");
		if (geoPoint != null) 
		{
			estacionesData.getDataFromServer(this);
		}
		else 
		{
			Log.d(TAG, "Delaying data update till location avaiable");
			updateWhenLocationAvaiable = true;
		}
	}

	private GeoPoint location2GeoPoint(Location location) {
		if (location == null) return null;
		
		Double lat = location.getLatitude()*1E6;
		Double lon = location.getLongitude()*1E6;			
		GeoPoint elGeoPoint = new GeoPoint(lat.intValue(),lon.intValue());
		
		return elGeoPoint;
	}
	
	public void onLocationChanged(Location location) {
		if (lastLocationProvider == null || lastLocationProvider.equals(providerCoarse)) 
		{
			lastLocationProvider = location.getProvider();
			Log.d(TAG, "Received location from provider " + lastLocationProvider);
				
			geoPoint = location2GeoPoint(location);
			estacionesData.setLocationPoint(geoPoint);
			Log.d(TAG, "Location Changed GeoPoint="+geoPoint);

			MyAdManager.setLocation(location);
			
			if (updateWhenLocationAvaiable) 
			{
				updateData();
			}
			updateWhenLocationAvaiable = false;
		}
	}

	public void onProviderDisabled(String provider) {
	}

	public void onProviderEnabled(String provider) {
	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	public void endQueryError() {
		handler.sendMessage(Message.obtain(handler, MESSAGE_LOADING_ERROR));
	}

	public void endQueryOk() {
		handler.sendMessage(Message.obtain(handler, MESSAGE_LOADING_OK));
	}

	public void startQuery() {
		handler.sendMessage(Message.obtain(handler, MESSAGE_LOADING_START));
	}

	/**
	 * Called to update
	 */
	Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			update(msg);
		}
	};
	
	void update(Message msg) {
		switch(msg.what) {
		case MESSAGE_LOADING_START:
			showLoading();
			break;
		case MESSAGE_LOADING_OK:
			if (loadingDialog == null) return;
			loadingDialog.dismiss();
			break;
		case MESSAGE_LOADING_ERROR:
			if (loadingDialog == null) return;
			loadingDialog.dismiss();
			
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setCancelable(false);
			builder.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
				}
			});		
			builder.setTitle(R.string.aviso);
			
			// comprobamos si tenemos un error generico, entonces le sacamos
			if ( estacionesData.getError() != null  )
				builder.setMessage(estacionesData.getError());				
			else // tenemos un error general
				builder.setMessage(R.string.error_data);
			
			AlertDialog errorDialog = builder.create();
			errorDialog.show();
			break;
		}
	}
	
	private void showLoading() {
		if (loadingDialog != null && loadingDialog.isShowing()) return;
		loadingDialog = ProgressDialog.show(this, "", getResources().getText(R.string.loading), true, true);
		loadingDialog.show();
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)  {
	    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
	    	whenLoadedAutomatically = 0;
	    }

	    return super.onKeyDown(keyCode, event);
	}

	private boolean hayDatosEstaciones()
	{
		boolean hay = false;
		if ( estacionesData.getEstaciones().size() > 0 )
		{
			hay = true;
		}
		return hay;
	}
	
	private boolean recibidosDatosEstaciones()
	{
		boolean hay = false;
		if ( estacionesData.isRespuestaCorrecta() )
		{
			hay = true;
		}
		return hay;
	}
	
	private void mostrarMensajeError(int id)
	{
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setCancelable(false);
		builder.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
			}
		});		
		builder.setTitle(R.string.error);	
		builder.setMessage(id);
		
		AlertDialog errorDialog = builder.create();
		errorDialog.show();
	}
	
	public void onMapAction(View v) 
	{
		if ( hayDatosEstaciones() )
		{
			Intent intent = new Intent(getApplicationContext(), TopGasMapActivity.class);
			Bundle bundle = new Bundle();
			
			String combustible = estacionesData.getCombustible();		
			combustible = Constantes.getDescripcionCombustible(combustible);
			bundle.putString(Constantes.ATRIBUTO_TITULO, "Mapa : " + combustible);
			
			intent.putExtras(bundle);				

			startActivity(intent);
		}
		else
		{
			if ( recibidosDatosEstaciones() )
			{
				mostrarMensajeError(R.string.error_no_estaciones);				
			}
			else
			{
				mostrarMensajeError(R.string.error_data);
			}

		}
	}

	public void onListActionPrecio(View v) 
	{
		if ( hayDatosEstaciones() )
		{
		
			estacionesData.ordenarEstaciones(this,"PRECIO");
			
			Intent intent = new Intent(getApplicationContext(), TopGasListActivity.class);
			Bundle bundle = new Bundle();
			
			String combustible = estacionesData.getCombustible();		
			combustible = Constantes.getDescripcionCombustible(combustible);
			bundle.putString(Constantes.ATRIBUTO_TITULO, "Por precio : " + combustible);
			
			intent.putExtras(bundle);		
			startActivity(intent);
		}
		else
		{
			if ( recibidosDatosEstaciones() )
			{
				mostrarMensajeError(R.string.error_no_estaciones);				
			}
			else
			{
				mostrarMensajeError(R.string.error_data);
			}

		}
			
	}

	public void onListActionDistancia(View v) 
	{
		if ( hayDatosEstaciones() )
		{
			estacionesData.ordenarEstaciones(this,"DISTANCIA");		
	
			
			Intent intent = new Intent(getApplicationContext(), TopGasListActivity.class);
			Bundle bundle = new Bundle();
			
					
			String combustible = estacionesData.getCombustible();			
			combustible = Constantes.getDescripcionCombustible(combustible);
			bundle.putString(Constantes.ATRIBUTO_TITULO, "Por distancia : " + combustible);
			
			intent.putExtras(bundle);				
			startActivity(intent);
		}
		else
		{
			if ( recibidosDatosEstaciones() )
			{
				mostrarMensajeError(R.string.error_no_estaciones);				
			}
			else
			{
				mostrarMensajeError(R.string.error_data);
			}

		}		
	}
	
	public void onRefreshAction(View v) 
	{
		updateData();
	}

/*	
	public void onPreferencesAction(View v) {
		Intent intent = new Intent(getApplicationContext(), PreferencesActivity.class);
		startActivity(intent);
	}
	
	public void onPreferencesDescuentosAction(View v) {
		Intent intent = new Intent(getApplicationContext(), PreferencesDescuentosActivity.class);
		startActivity(intent);
	}	
	*/
	public void onPreferencesAction(View v) 
	{
		Intent intent = new Intent(getApplicationContext(), PreferencesActivity.class);
		
		Bundle bundle = new Bundle();		
		bundle.putString(Constantes.ATRIBUTO_PREFERENCIAS_MOSTRAR, "generales");		
		intent.putExtras(bundle);				

		startActivity(intent);

	}
	
	public void onPreferencesDescuentosAction(View v) 
	{
		Intent intent = new Intent(getApplicationContext(), PreferencesActivity.class);
		
		Bundle bundle = new Bundle();		
		bundle.putString(Constantes.ATRIBUTO_PREFERENCIAS_MOSTRAR, "descuentos");		
		intent.putExtras(bundle);				

		startActivity(intent);

	}	
	
	
	
	
	
}